﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace Diplom.Forms
{
    public partial class WaveletsDesigner : Form
    {
        NumericArrays.Numeric1DArray array1D = null;
        string waveletType = string.Empty;

        public WaveletsDesigner()
        {
            InitializeComponent();
        }

        private void refreshButton_Click(object sender, EventArgs e)
        {
            int length;
            double a;
            double b;

            try
            {
                length = (int)numericUpDown1.Value;
            }
            catch (Exception ex)
            {
                textBox1.Text = ex.ToString();
                return;
            }

            try
            {
                string[] strs = intervalTextBox.Text.Split(new string[4] { " ", ",", ":", ";" }, StringSplitOptions.RemoveEmptyEntries);
                if (strs.Length != 2) throw new Exception("Incorrect Interval");
                a = Convert.ToDouble(strs[0]);
                b = Convert.ToDouble(strs[1]);
            }
            catch (Exception ex)
            {
                textBox1.Text = ex.ToString();
                return;
            }

            if (string.IsNullOrEmpty(comboBox1.Text))
            {
                textBox1.Text = "Please select Wavelet";
                return;
            }

            switch (comboBox1.Text)
            {
                case "MHAT":
                    {
                        array1D = new Diplom.NumericArrays.Numeric1DArray(length);
                        double h = (b - a) / length;
                        int i=0;
                        for (double x = a; x <= b; x += h)
                        {
                            if (i == length) break;
                            double res = (1 - x * x);
                            res *= Math.Exp(-x * x * 0.5);
                            array1D.Insert(i, res);
                            i++;
                        }
                        array1D.InitCharacters();
                    } break;
                case "Real part Morlet":
                    {
                        array1D = new Diplom.NumericArrays.Numeric1DArray(length);
                        double h = (b - a) / length;
                        int i = 0;
                        for (double x = a; x <= b; x += h)
                        {
                            if (i == length) break;
                            double res = Math.Exp(-x * x / 2.0) * Math.Cos(2 * Math.PI * x);
                            array1D.Insert(i, res);
                            i++;
                        }
                        array1D.InitCharacters();
                    } break;
                case "WAVE":
                    {
                        array1D = new Diplom.NumericArrays.Numeric1DArray(length);
                        double h = (b - a) / length;
                        int i = 0;
                        for (double x = a; x <= b; x += h)
                        {
                            if (i == length) break;
                            double res = -x * Math.Exp(-x * x * 0.5);
                            array1D.Insert(i, res);
                            i++;
                        }
                        array1D.InitCharacters();
                    } break;
                case "DOG":
                    {
                        array1D = new Diplom.NumericArrays.Numeric1DArray(length);
                        double h = (b - a) / length;
                        int i = 0;
                        for (double x = a; x <= b; x += h)
                        {
                            if (i == length) break;
                            double res = Math.Exp(-x * x * 0.5) - 0.5 * Math.Exp(-x * x / 8.0);
                            array1D.Insert(i, res);
                            i++;
                        }
                        array1D.InitCharacters();
                    } break;
                case "HAAR":
                    {
                        array1D = new Diplom.NumericArrays.Numeric1DArray(length);
                        double h = (b - a) / length;
                        int i = 0;
                        for (double x = a; x <= b; x += h)
                        {
                            if (i == length) break;
                            double res;
                            if (x < 0) res = 0.0;
                            else if (x < 0.5) res = 1.0;
                            else res = -1.0;
                            array1D.Insert(i, res);
                            i++;
                        }
                        array1D.InitCharacters();
                    } break;
                case "LP-LittleWood_Paley":
                    {
                        array1D = new Diplom.NumericArrays.Numeric1DArray(length);
                        double h = (b - a) / length;
                        int i = 0;
                        for (double x = a; x <= b; x += h)
                        {
                            if (i == length) break;
                            double res;
                            if (Math.Abs(x) < 1e-6) res = 0.0;
                            else res = (Math.Sin(2*Math.PI*x)-Math.Sin(Math.PI*x))/(Math.PI*x);
                            array1D.Insert(i, res);
                            i++;
                        }
                        array1D.InitCharacters();
                    } break;
                case "FHAT":
                    {
                        array1D = new Diplom.NumericArrays.Numeric1DArray(length);
                        double h = (b - a) / length;
                        int i = 0;
                        for (double x = a; x <= b; x += h)
                        {
                            if (i == length) break;
                            double res;
                            if (x < -1.0) res = 0.0;
                            else if (3 * x < -1.0) res = -0.5;
                            else if (3 * x < 1.0) res = 1.0;
                            else if (x < 1.0) res = -0.5;
                            else res = 0.0;
                            array1D.Insert(i, res);
                            i++;
                        }
                        array1D.InitCharacters();
                    } break;
            }
            waveletType = comboBox1.Text;
            this.RePaint();
        }


        private void WaveletsDesigner_Load(object sender, EventArgs e)
        {
            comboBox1.SelectedIndex = 0;
        }

        private void RePaint()
        {
            if (array1D != null)
            {
                Image img = new Bitmap(waveletPicture.Width, waveletPicture.Height);
                System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(img);
                graphics.Clear(Color.White);
                Graphics.D2D.DrawStyle drawStyle = new Diplom.Graphics.D2D.DrawStyle(Color.Blue, new Point(0, 0), new Point(1, 1), Color.Red, Color.Green);
                Graphics.D2D.D2DVisualizer.DrawGraphic(ref graphics, ref array1D,
                    new RectangleF(
                        new PointF((float)50, (float)30),
                        new SizeF((float)waveletPicture.Width - 100, (float)waveletPicture.Height - 60)),
                    drawStyle);

                Graphics.D2D.D2DVisualizer.DrawSignature(ref graphics, ref array1D,
                    new RectangleF(
                        new PointF((float)50, (float)30),
                        new SizeF((float)waveletPicture.Width - 100, (float)waveletPicture.Height - 60)),
                    drawStyle, new Size(25, 10));

                graphics.DrawString(waveletType, new Font("Times New Roman", 7), Brushes.Red,
                    new PointF(10, 10));

                waveletPicture.Image = img;
            }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            refreshButton_Click(sender, e);
        }

        private void saveButton_Click(object sender, EventArgs e)
        {
            if (array1D != null && waveletPicture.Image != null)
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.AddExtension = true;
                saveFileDialog.CheckPathExists = true;
                saveFileDialog.Filter = "Jpeg files|*.jpg";
                saveFileDialog.InitialDirectory = Path.GetDirectoryName(Application.ExecutablePath);
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    waveletPicture.Image.Save(saveFileDialog.FileName, System.Drawing.Imaging.ImageFormat.Jpeg);
                }
            }
        }

        private void WaveletsDesigner_ResizeEnd(object sender, EventArgs e)
        {
            this.RePaint();
        }
    }
}
